﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Common.CommandTrees;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Web.Http;
using WordsOfLoveServer.Models;
using WordsOfLoveServer.Models.Forums;

namespace WordsOfLoveServer.Controllers
{
    public class ForumPostController : ApiController
    {
		#region Post APIs
		// GET: api/ForumPost/GetPosts?title=xxx&tag=xxx
		[HttpGet]
		public HttpResponseMessage GetPosts(string title, string tag)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					IQueryable<ForumPost> posts = db.ForumPosts;
					if (title != null) posts = posts.Where(post => post.Title.Contains(title));
					if (tag != null)
					{
						posts =
							from x in db.ForumPosts
							join y in db.ForumPostTags
							on x.Id equals y.PostId
							where y.Content == tag
							select x;
					}
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(posts.ToList()))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// GET: api/ForumPost/GetAllPosts
		[HttpGet]
		public HttpResponseMessage GetAllPosts()
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					IQueryable<ForumPost> posts = db.ForumPosts;
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(posts.ToList()))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// GET: api/ForumPost/GetPostById?id=xxx
		[HttpGet]
		public HttpResponseMessage GetPostById(int id)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					ForumPost post = db.ForumPosts.Find(id);
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(post))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// POST: api/ForumPost/CreatePost
		[HttpPost]
		public HttpResponseMessage CreatePost([FromBody] ForumPost post)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumPosts.Add(post);
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.Created);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		//DELETE: api/ForumPost/DeletePost?id=xxx
		[HttpDelete]
		public HttpResponseMessage DeletePost(int id)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					ForumPost post = db.ForumPosts.Find(id);
					if (post == null)
					{
						return new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("Item doesn't exist.") };
					}
					db.ForumPosts.Remove(post);
					db.SaveChanges();
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
			return new HttpResponseMessage(HttpStatusCode.OK);
		}

		// PUT: api/ForumPost/UpdatePost
		[HttpPut]
		public HttpResponseMessage UpdatePost([FromBody] ForumPost post)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.Entry(post).State = EntityState.Modified;
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.OK);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		#endregion

		#region PostTag APIs
		// GET: api/ForumPost/GetTags?postId=xxx
		[HttpGet]
		public HttpResponseMessage GetTags(int postId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					List<ForumPostTag> tags = db.ForumPostTags.Where(x => x.PostId == postId).ToList();
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(tags))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// PUT: api/ForumPost/CreateTag
		[HttpPut]
		public HttpResponseMessage CreateTag(ForumPostTag tag)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumPostTags.Add(tag);
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.Created);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// DELETE: api/ForumPost/DeleteTag?postId=xxx&tag=xxx
		[HttpDelete]
		public HttpResponseMessage DeleteTag(int postId, string tag)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumPostTags.Remove(new ForumPostTag() { PostId = postId, Content = tag });
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.OK);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		#endregion

		#region PostLike APIS
		// GET: api/ForumPost/GetLikeCount?postId=xxx
		[HttpGet]
		public HttpResponseMessage GetLikeCount(int postId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					int count = db.ForumPostLikes.Where(x => x.PostId == postId).Count();
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(count))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// GET: api/ForumComment/GetLike?postId=xxx&userId=xxx
		[HttpGet]
		public HttpResponseMessage GetLike(int postId, int userId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					ForumPostLike like = db.ForumPostLikes.Find(userId, postId);
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(like))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// PUT: api/ForumPost/CreateLike
		[HttpPut]
		public HttpResponseMessage CreateLike([FromBody] ForumPostLike like)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumPostLikes.Add(like);
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.Created);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// DELETE: api/ForumPost/DeleteLike?postId=xxx&userId=xxx
		[HttpDelete]
		public HttpResponseMessage DeleteLike(int postId, int userId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumPostLikes.Remove(new ForumPostLike() { PostId = postId, UserId = userId });
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.OK);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		#endregion
	}

	public class ForumCommentController : ApiController
	{
		#region PostComment APIs
		// GET: api/ForumComment/GetComments?PostId=xxx
		[HttpGet]
		public HttpResponseMessage GetComments(int postId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					IQueryable<ForumComment> comments = db.ForumComments.Where(x => x.PostId == postId);
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(comments.ToList()))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// POST: api/ForumComment/CreateComment
		[HttpPost]
		public HttpResponseMessage CreateComment([FromBody] ForumComment comment)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumComments.Add(comment);
					db.SaveChanges();
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
			return new HttpResponseMessage(HttpStatusCode.Created);
		}

		// PUT: api/ForumComment/UpdateComment
		[HttpPut]
		public HttpResponseMessage UpdateComment([FromBody] ForumComment comment)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.Entry(comment).State = EntityState.Modified;
					db.SaveChanges();
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
			return new HttpResponseMessage(HttpStatusCode.OK);
		}

		//DELETE: api/ForumComment/DeleteComment/xxx
		[HttpDelete]
		public HttpResponseMessage DeleteComment(int id)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					ForumComment comment = db.ForumComments.Find(id);
					if (comment == null)
					{
						return new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("Item doesn't exist.") };
					}
					db.ForumComments.Remove(comment);
					db.SaveChanges();
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
			return new HttpResponseMessage(HttpStatusCode.OK);
		}

		#endregion

		#region PostCommentLike APIs
		// GET: api/ForumComment/GetLikeCount?commentId=xxx
		[HttpGet]
		public HttpResponseMessage GetLikeCount(int commentId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					int count = db.ForumCommentLikes.Where(x => x.CommentId == commentId).Count();
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(count))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// GET: api/ForumComment/GetLike?postId=xxx&userId=xxx
		[HttpGet]
		public HttpResponseMessage GetLike(int commentId, int userId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					ForumCommentLike like = db.ForumCommentLikes.Find(userId, commentId);
					return new HttpResponseMessage()
					{
						RequestMessage = Request,
						Content = new StringContent(JsonConvert.SerializeObject(like))
					};
				}
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// PUT: api/ForumComment/CreateLike
		[HttpPut]
		public HttpResponseMessage CreateLike([FromBody] ForumCommentLike like)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumCommentLikes.Add(like);
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.Created);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}

		// DELETE: api/ForumComment/DeleteLike?postId=xxx&userId=xxx
		[HttpDelete]
		public HttpResponseMessage DeleteLike(int commentId, int userId)
		{
			try
			{
				using (var db = new WOLDbContext())
				{
					db.ForumCommentLikes.Remove(new ForumCommentLike() { CommentId = commentId, UserId = userId });
					db.SaveChanges();
				}
				return new HttpResponseMessage(HttpStatusCode.OK);
			}
			catch (Exception ex)
			{
				return new HttpResponseMessage(HttpStatusCode.BadRequest)
				{
					Content = new StringContent(ex.Message)
				};
			}
		}
		#endregion
	}

}
